#include <iostream>
#include <cstring>
#include <unistd.h>
#include <sys/socket.h> 
#include <sys/types.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <pthread.h>
using namespace std;

const int PORT = 8081;
const int NUM = 5; 


void* RUN(void* arg)
{
  pthread_detach(pthread_self());
  int fd = *(int*)arg;
  delete arg;
  while(1)
  {
    cout << "sockfd" << fd << "is severing the client" << endl;
    sleep(1);
  }

  return nullptr;
}




int main()
{
  int listen_socket = socket(AF_INET , SOCK_STREAM , 0); 
  if (listen_socket < 0) 
  {
    cerr << "listen_socket error" << endl; 
    exit(1);
  }
  int opt = 1;
setsockopt(listen_socket, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));


  struct sockaddr_in local;
  memset(&local , '\0' , sizeof(local));
  local.sin_family = AF_INET;
  local.sin_port = htons(PORT);
  local.sin_addr.s_addr =  INADDR_ANY;

  if (bind(listen_socket , (struct sockaddr*)&local , sizeof(local)) < 0)
  {
    cerr << "bind error" << endl;
    exit(2);
  }

  if(listen(listen_socket , NUM) < 0) 
  {
    cerr << "listen error" << endl;
    exit(3);
  }

  // peer 
  struct sockaddr_in peer;
  memset(&peer , '\0' , sizeof(peer));
  socklen_t len = sizeof(peer);

  for(;;)
  {
    int sockfd = accept(listen_socket , (struct sockaddr*)&peer , &len);
    if (sockfd < 0)
    {
      cerr << "accept error" << endl;
      continue;
    }

    cout << "get a new linl:" << endl;
    int* p = new int(sockfd);

    pthread_t tid;
    pthread_create(&tid , nullptr , RUN , (void*)p);
  }


  return 0;
}
